package com.asset.dispoal.evidenceconfig.service;

import com.asset.dispoal.evidenceconfig.api.BsEvidenceConfService;
import com.asset.dispoal.evidenceconfig.domain.db.entity.BsEvidenceConf;
import com.asset.dispoal.evidenceconfig.domain.db.mapper.BsEvidenceConfItemDetailMapper;
import com.asset.dispoal.evidenceconfig.domain.db.mapper.BsEvidenceConfItemMapper;
import com.asset.dispoal.evidenceconfig.domain.db.mapper.BsEvidenceConfMapper;
import com.asset.dispoal.evidenceconfig.domain.dto.EvidenceConfQueryIdsDto;
import com.asset.dispoal.evidenceconfig.domain.dto.EvidenceConfRespIdsDto;
import com.asset.dispoal.evidenceconfig.dto.request.BsEvidenceConfRequest;
import com.asset.dispoal.evidenceconfig.dto.response.BsEvidenceConfResponse;
import com.asset.dispoal.evidenceconfig.service.converter.BsEvidenceConfConverter;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import tech.mhuang.pacebox.core.exception.BusinessException;
import tech.mhuang.pacebox.core.id.BaseIdeable;
import tech.mhuang.pacebox.core.util.CollectionUtil;
import tech.mhuang.pacebox.core.util.StringUtil;
import tech.mhuang.pacebox.springboot.core.local.GlobalHeaderThreadLocal;
import tech.mhuang.pacebox.springboot.core.protocol.page.PageUtil;
import tech.mhuang.pacebox.springboot.core.spring.util.DataUtil;
import tech.mhuang.pacebox.springboot.protocol.Result;
import tech.mhuang.pacebox.springboot.protocol.data.Page;
import tech.mhuang.pacebox.springboot.protocol.data.PageVO;

import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author qr
 * @date 2021/10/21$
 */
@Service
public class BsEvidenceConfServiceImpl implements BsEvidenceConfService {

    @Autowired
    private BsEvidenceConfMapper bsEvidenceConfMapper;

    @Autowired
    BaseIdeable<String> snowFlake;

    @Autowired
    BsEvidenceConfItemMapper bsEvidenceConfItemMapper;

    @Autowired
    BsEvidenceConfItemDetailMapper bsEvidenceConfItemDetailMapper;


    @Override
    public PageVO<BsEvidenceConfResponse> findEvidenceConf(BsEvidenceConfRequest bsEvidenceConfRequest) {
        PageVO<BsEvidenceConfResponse> pageVo = new PageVO<>();
        if (bsEvidenceConfRequest == null) {
            bsEvidenceConfRequest = new BsEvidenceConfRequest();
        }
        pageVo.setTotalSize(bsEvidenceConfMapper.findEvidenceConfCount(bsEvidenceConfRequest));
        if (PageUtil.checkPage(pageVo.getTotalSize(), bsEvidenceConfRequest)) {
            Page<BsEvidenceConfRequest> page = new Page<>();
            page.setRecord(bsEvidenceConfRequest);
            page.setStart((bsEvidenceConfRequest.getStart() - 1) * bsEvidenceConfRequest.getRows());
            page.setRows(bsEvidenceConfRequest.getRows());
            final List<BsEvidenceConf> evidenceConf = bsEvidenceConfMapper.findEvidenceConf(page);
            final List<BsEvidenceConfResponse> bsEvidenceConfResponses = BsEvidenceConfConverter.INSTANCE.dosToRes(evidenceConf);
            pageVo.setResult(bsEvidenceConfResponses);
        }
        return pageVo;
    }

    @Override
    public void insertOrUpdate(BsEvidenceConfRequest bsEvidenceConfRequest) {
        if (bsEvidenceConfRequest == null) {
            throw new BusinessException(Result.SYS_FAILD, "参数错误(请求对象为空)");
        }
        BsEvidenceConf bsEvidenceConf = DataUtil.copyTo(bsEvidenceConfRequest, BsEvidenceConf.class);
        String userId = GlobalHeaderThreadLocal.getOrException().getUserId();
        if (StringUtil.isBlank(bsEvidenceConfRequest.getId())) {
            //添加
            if (StringUtil.isBlank(bsEvidenceConf.getConfCode()) || StringUtil.isBlank(bsEvidenceConf.getConfName()) || StringUtil.isBlank(bsEvidenceConf.getAssetInstBatchId())) {
                throw new BusinessException(Result.SYS_FAILD, "参数错误(配置编码/配置名称/批次id)不能为空");
            }
            bsEvidenceConf.setId(snowFlake.generateId());
            bsEvidenceConf.setCreateUser(userId);
            bsEvidenceConf.setCreateTime(new Date());
            bsEvidenceConfMapper.insert(bsEvidenceConf);
        } else {
            //修改
            //验证当前数据是否存在
            final BsEvidenceConf byId = bsEvidenceConfMapper.getById(bsEvidenceConf.getId());
            if (byId == null) {
                throw new BusinessException(Result.SYS_FAILD, "修改数据不存在 id" + bsEvidenceConf.getId());
            }
            BsEvidenceConf newBsEvidenceConf = new BsEvidenceConf();
            DataUtil.copyProperties(byId, newBsEvidenceConf, getNullPropertyNames(byId));
            DataUtil.copyProperties(bsEvidenceConf, newBsEvidenceConf, getNullPropertyNames(bsEvidenceConf));
            newBsEvidenceConf.setOperateUser(userId);
            newBsEvidenceConf.setOperateTime(new Date());
            bsEvidenceConfMapper.update(newBsEvidenceConf);
        }
    }

    public static String[] getNullPropertyNames(Object source) {
        final BeanWrapper src = new BeanWrapperImpl(source);
        java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();
        Set<String> emptyNames = new HashSet<>();
        for (java.beans.PropertyDescriptor pd : pds) {
            //check if value of this property is null then add it to the collection
            Object srcValue = src.getPropertyValue(pd.getName());
            if (srcValue == null) {//特定字符写在此处过滤，收集不需要copy的字段列表。此处过滤null为例
                emptyNames.add(pd.getName());
            }
        }
        String[] result = new String[emptyNames.size()];
        return emptyNames.toArray(result);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void del(BsEvidenceConfRequest bsEvidenceConfRequest) {
        //关联信息全部删除
        final String id = bsEvidenceConfRequest.getId();
        EvidenceConfQueryIdsDto confQueryIdsDto = new EvidenceConfQueryIdsDto();
        confQueryIdsDto.setConfId(id);
        List<EvidenceConfRespIdsDto> itemAndDetailIds = bsEvidenceConfMapper.findItemAndDetailIds(confQueryIdsDto);
        if (CollectionUtil.isNotEmpty(itemAndDetailIds)) {
            itemAndDetailIds.forEach(item -> {
                if (StringUtil.isNotBlank(item.getConfItemIds())) {
                    bsEvidenceConfItemMapper.delete(item.getConfItemIds());
                }
                if (StringUtil.isNotBlank(item.getItemDetailIds())) {
                    bsEvidenceConfItemDetailMapper.delete(item.getItemDetailIds());
                }
            });
        }
        bsEvidenceConfMapper.delete(id);

    }

    @Override
    public List<Map<String, String>> findListByBatchId(String batchId) {
        return bsEvidenceConfMapper.findListByBatchId(batchId);
    }


}
